import local from '@/common/local.js'
import store from '@/store'
import util from '@/common/util';
import serveRoots from "@/project/serveRoots.js"

function upls1(url, options = {}) {
	options = Object.assign({}, options);
	const root = local.env.rootMap['http5'];
	// header
	let authorization;
	try {
		authorization = store.state.User.userInfo.jxyUserInfo.token;
	} catch (e) {
		authorization = ''
	}
	const header = {
		'Content-Type': 'application/x-www-form-urlencoded',
		authorization
	}
	Object.assign(header, options.header)
	return uploadFiles(root, url, {
		...options,
		header
	})
}

// 兼容微信小程序多文件上传的文件上传
// 1. 通过 files 区分 单/多 文件上传；
// 2. 为自定义的数据返回，且不存在对外抛出异常的情况；
// 3. 未兼容传 file 的上传逻辑；
function uploadFiles(root = '', url, options = {}) {
	options = Object.assign({}, options);
	const pros = [];
	const files = options.files;
	if (files) {
		// 1. 存在 filse 时为多文件上传
		delete options.files;
		for (let i of files) {
			const opts = {
				...options,
				filePath: i.uri,
				name: i.name || util.getUuid()
			}
			pros.push(uploadFile(root, url, opts).catch(err => {
				// 1.2. 文件上传失败时附带本地图片的 filePath 和 name 信息
				return {
					...err,
					options: opts
				}
			}))
		}
	} else {
		// 2. 不存在 filse 时为单文件上传
		const opts = {
			...options,
			name: options.name || util.getUuid()
		};
		pros.push(uploadFile(root, url, opts).catch(err => {
			return {
				...err,
				options: opts
			}
		}))
	}
	return new Promise(async reslove => {
		// 3. 并发上传
		const ress = await Promise.all(pros);
		const successData = [];
		const errorData = [];
		for (const i in ress) {
			const res = ress[i];
			if (res.status !== 1) {
				errorData.push(res);
				continue;
			}
			if (res.result.rows[0].status !== 1) {
				errorData.push(res.result.rows[0]);
				continue;
			}
			successData.push(res.result.rows[0].result);
		}
		reslove({
			count: ress.length,
			successData,
			successCount: successData.length,
			errorData,
			errorCount: ress.length - successData.length
		})
	})
}

// 基础文件上传
// 1. 由于微信小程序限制，基础上传 api 不支持多文件上传；
// 2. 只要有一张上传错误就会直接对外抛出异常;
function uploadFile(root = '', url_, options = {}) {
	options = Object.assign({}, options);
	// url
	const url = local.env.server + root + serveRoots.prefixUrl + (ifObject(url_) ? url_.url : url_)
	// header
	const header = {
		SYS_SIGN: 'APP'
	}
	Object.assign(header, options.header)
	return new Promise((reslove, reject) => {
		const uploadTask = uni.uploadFile({
			timeout: 60000,
			...options,
			url,
			header,
			success: res => {
				res = JSON.parse(res.data);
				if (res.status !== 1) return reject(res);
				for (let i of res.result.rows) {
					if (i.status !== 1) return reject(i);
				}
				reslove(res);
			},
			fail: err => {
				reject(err);
			}
		});
		uploadTask.onProgressUpdate(res => {
			if (typeof options.onProgressUpdate === 'function') {
				uploadTask.onProgressUpdate(res)
			}
		});
	});
}

function ifObject(data) {
	return typeof data === 'object' && !Array.isArray(data) && data !== null;
}

module.exports = {
	upls1
}
